'''
Created on 2010/07/06

@author: yukiyonezawa
'''
from pyrfid.DataProtocol.AddObject import AddObject
from pyrfid.asn1.Encoder import Encoder
from pyrfid.DataProtocol.DSFID.DSFID import DSFID
from pyrfid.DataProtocol.Driver.UHFDriver import UHFDriver
from pyrfid.asn1.Decoder import Decoder
from pyrfid.DataProtocol.Exception.CompletionCodeException.CompletionCodeException import CompletionCodeException
from pyrfid.DataProtocol.Exception.ExecutionCodeException.ExecutionCodeException import ExecutionCodeException
from pyrfid.ApplicationInterface.argument.WriteResponses import WriteResponses

class WriteObjectsSegmentedMemoryTagCRU(object):
    '''
    classdocs
    '''
    dsfid = object()
    dsfid_on_tag = object()
    access_method = object()
    command_list = object()
    TAG_ID = str()
    start_data_set_address = int()
    driver = object()
    
    MEMORY_UII = "0"
    MEMORY_TID = "1"
    MEMORY_USER = "2"
    
#    completion_code = dict()
    completion_code = 0
    execution_code = 0
    add_objects_list = list()
    
        
    def __init__(self, tag_id, dsfid, command_list, driver):
        '''
        Constructor
        '''
        self.TAG_ID = tag_id        
        self.dsfid_on_tag = dsfid
        self.command_list = command_list
        self.driver = driver
    
    def execute(self):
        
        #handle command_list
        memory_bank = self.command_list.popElement().VALUE
        access_password = self.command_list.popElement().VALUE
        application_family = self.command_list.popElement().VALUE        
        application_subfamily = self.command_list.popElement().VALUE        
        access_method = self.command_list.popElement().VALUE        
        data_format_id = self.command_list.popElement().VALUE
        
        dsfid = DSFID(access_method, data_format_id)
        dsfid.access_method.setDriver(self.driver)
        print "dsfid is ",dsfid.getLogicalMemory()
        
        #for New Tag 
        if self.dsfid_on_tag == "":
            #@todo: change configure DSFID
            self.driver.configureDSFID(self.TAG_ID, dsfid.getLogicalMemory())
        
#@todo: check the data_format
#        if data_format != self.dsfid.DATA_FORMAT.DATA_FORMAT_ID:
#            return False
        
        #pop 30
        self.command_list.popElement().VALUE        
        for index in range(self.command_list.getLengthElement() / 5):
            object_identifier = Encoder.oidEncode(self.command_list.popElement().VALUE)
            
            avoid_duplicate = self.command_list.popElement().VALUE
            
            object_value = Encoder.octetStrEncode(self.command_list.popElement().VALUE)
            
            compact_parameter = self.command_list.popElement().VALUE
            
            object_lock = Encoder.boolEncode(self.command_list.popElement().VALUE)
            
            add_object = AddObject(object_identifier, avoid_duplicate, object_value, compact_parameter, object_lock)
            add_object.show()
            print "-"
            self.add_objects_list.append(add_object)
        
        print "------------------------------------------"
        print self.dsfid_on_tag
        print access_method
        print "------------------------------------------"
        
        if self.dsfid_on_tag != "" and self.dsfid_on_tag.access_method.ACCESS_METHOD_ID != access_method:
            print "Access-Method Miss Match"
            raise "Access-Method Miss Match"
        
        #check compaction type
        for add_object in self.add_objects_list:
            if str(add_object.COMPACT_PARAMETER) not in dsfid.access_method.ALLOW_COMPACTION_TYPE:
                print "COMPACTION PARAMETER DOES NOT SUPPOETED"
                raise "COMPACTION PARAMETER DOES NOT SUPPOETED"
        

        
#        try:
        if memory_bank == self.MEMORY_USER:
            dsfid.access_method.addData(self.TAG_ID, self.dsfid_on_tag, dsfid.data_format, self.add_objects_list)
        elif memory_bank == self.MEMORY_UII:
            dsfid.access_method.addDataOnUII(self.TAG_ID, self.dsfid_on_tag, dsfid.data_format, self.add_objects_list)
#        except CompletionCodeException as error:
#            self.completion_code = error.COMPLETION_CODE
#        except ExecutionCodeException as error:
#            self.execution_code = error.EXECUTION_CODE
            
#    def addedObjectIdentifier(self, oid, completion_code):
#        self.completion_code[oid] = completion_code    
    
    
    def encode(self, cru_id):
        encoder = Encoder()
        listRSPAndData = []
        listRSPAndData.append(['06', '05', Encoder.oidEncode(cru_id)])
        listRSPAndData.append([Decoder.SEQUENCE_AND_SEQUENCE_OF, '', ''])
        
        #objects:SEQUENCE OF SEQUENCE
        listRSPAndData.append([Decoder.SEQUENCE_AND_SEQUENCE_OF, '', ''])
        
        objectLength = 0
#        if self.EXECUTION_CODE == self.NO_ERROR and self.COMPLETION_CODE == self.NO_ERROR:
        for add_object in self.add_objects_list:
            
            #objectId:OBJECT_IDENTIFIER
            objectIdentifierLengthHex = encoder.lengthEncode(len(add_object.OBJECT_IDENTIFIER) / 2)
            listRSPAndData.append([Decoder.OBJECT_IDENTIFIER, objectIdentifierLengthHex, add_object.OBJECT_IDENTIFIER])
            objectLength += int(objectIdentifierLengthHex, 16)

            #completion_code        
            if self.completion_code != 0 and self.execution_code != 0:
                listRSPAndData.append([Decoder.INTEGER, '01' , encoder.intEncode(WriteResponses.COMPLETION_CODE_OBJECT_NOT_ADDED)])
            else:
                listRSPAndData.append([Decoder.INTEGER, '01' , encoder.intEncode(WriteResponses.COMPLETION_CODE_NO_ERROR)])
            objectLength += 1
        
        listRSPAndData[2][1] = encoder.lengthEncode(objectLength)

        #completion code:INTEGER
        listRSPAndData.append([Decoder.INTEGER, '01', encoder.intEncode(self.completion_code) ])
        
        #execution code:INTEGER
        listRSPAndData.append([Decoder.INTEGER, '01', encoder.intEncode(self.execution_code)])
        
        
        allLength = objectLength + 1 + 1
        listRSPAndData[1][1] = encoder.lengthEncode(allLength)
        
        rspHex = str()
        for l in listRSPAndData:
            print l
            for s in l:
                rspHex += str(s)
        return rspHex


